// ****************************************************************************
// *     Filename:  EventAction.cc
// *  Description:  
// *      License:  Geant4 Software License 
// *                http://geant4.cern.ch/license/LICENSE.html
// *       Author:  Tran Hoai Nam (nam), nam@kuno-g.phys.sci.osaka-u.ac.jp
// * Organization:  Osaka University
// *      Created:  2012-09-14 15:31:31
// ****************************************************************************

#include "G4Event.hh"
#include "G4HCofThisEvent.hh"
#include "G4SDManager.hh"

#include "EventAction.hh"
#include "MyHit.hh"
#include "HistoManager.hh"
#include "PrimaryGeneratorAction.hh"
#include <string>

EventAction::EventAction() 
{
	fpSDMan  = G4SDManager::GetSDMpointer();
}

EventAction::EventAction(PrimaryGeneratorAction *priGen) 
{
	fpPriGen = priGen;
	fpSDMan  = G4SDManager::GetSDMpointer();
}

EventAction::EventAction(HistoManager* histo, PrimaryGeneratorAction *priGen) 
{
	fpHistoMan = histo;
	fpPriGen= priGen;
	fpSDMan  = G4SDManager::GetSDMpointer();
}

EventAction::~EventAction() {;}

void EventAction::BeginOfEventAction(const G4Event* event) 
{
	//G4cout<<"hello\n";
}

void EventAction::EndOfEventAction(const G4Event* event)
{
	fpEvt = new TEvent();
	fpEvt->SetEvtId(event->GetEventID());
	ReadoutDetector(event,"aSD");
	//G4cout<<"endl!"<<G4endl;
	fpHistoMan->WriteEvt(fpEvt);
	fpHistoMan->FillTree();
}

void EventAction::ReadoutDetector(const G4Event *event, G4String detName) 
{
	G4int hitsCollID = fpSDMan->GetCollectionID(detName);
	if(hitsCollID >= 0)
	{
		G4HCofThisEvent *aHCE = event->GetHCofThisEvent();
		MyHitsCollection* hitsCollection= 
			dynamic_cast<MyHitsCollection*>(aHCE->GetHC(hitsCollID));
		G4int NoOfHits = hitsCollection->GetSize();
		//G4cout<<"Detetector: "<<detName<<", # of hits: "<<NoOfHits<<G4endl;
		//Scan all hits
		G4double Edep = 0.;
		for (int i=0;i<NoOfHits;i++)
		{
			MyHit* aHit = (*hitsCollection)[i];
				//aHit->Print();
			switch(aHit->GetHitType())
			{
				case MyHit::CaloHit:
					Edep += aHit->Getedep();
					break;
				case MyHit::TrackerHit:
					ProcessHit(aHit);
					break;
				default:
					break;
			}
		}
		fpEvt->AddEdep(Edep);
		//G4cout<<"Energy deposited: "<<Edep/MeV<<" MeV\n";
	}
}

void EventAction::ProcessHit(MyHit *aHit) 
{
	if(aHit->IsPriStopped())
	{
		aHit->Print();
		TTrackerHit aTrkHit;
		aTrkHit.SetHitType(TTrackerHit::PrimaryStopped);
		aTrkHit.SetTime(aHit->GetStopTime()/ns);
		G4ThreeVector aPos = aHit->GetStopPoint();
		aTrkHit.SetPos(aPos.x()/um,aPos.y()/um,aPos.z()/um);
		fpEvt->AddHit(aTrkHit);
	}	
	else if (aHit->GetDirection() == 1)
	{
		aHit->Print();
		TTrackerHit aTrkHit;
		aTrkHit.SetHitType(TTrackerHit::ParticleEntered);
		aTrkHit.SetTime(aHit->GetTime()/ns);
		aTrkHit.SetKE(aHit->GetKE()/keV);
		aTrkHit.SetPCode(aHit->GetPID());
		aTrkHit.SetTrackID(aHit->GetTrackID());
		G4ThreeVector aPos = aHit->GetPos();
		aTrkHit.SetPos(aPos.x()/um,aPos.y()/um,aPos.z()/um);
		fpEvt->AddHit(aTrkHit);
	}
	else if (aHit->GetDirection() == -1)
	{
		aHit->Print();
		TTrackerHit aTrkHit;
		aTrkHit.SetHitType(TTrackerHit::ParticleExited);
		aTrkHit.SetTime(aHit->GetTime()/ns);
		aTrkHit.SetKE(aHit->GetKE()/keV);
		aTrkHit.SetPCode(aHit->GetPID());
		aTrkHit.SetTrackID(aHit->GetTrackID());
		G4ThreeVector aPos = aHit->GetPos();
		aTrkHit.SetPos(aPos.x()/um,aPos.y()/um,aPos.z()/um);
		fpEvt->AddHit(aTrkHit);
	}
	else if (aHit->IsNew() && aHit->GetNewPID()==2112)
	{
		aHit->Print();
		TTrackerHit aTrkHit;
		aTrkHit.SetHitType(TTrackerHit::NewParticle);
		aTrkHit.SetTime(aHit->GetNewTime()/ns);
		aTrkHit.SetKE(aHit->GetNewKE()/keV);
		aTrkHit.SetPCode(aHit->GetNewPID());
		aTrkHit.SetTrackID(aHit->GetNewTrackID());
		G4ThreeVector aPos = aHit->GetNewPoint();
		aTrkHit.SetPos(aPos.x()/um,aPos.y()/um,aPos.z()/um);
		fpEvt->AddHit(aTrkHit);
	}
}
